package org.ioriframework.plugin.maven;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Set;

import org.ioriframework.plugin.maven.console.ConsoleFactory;
import org.ioriframework.plugin.maven.console.ConsoleService;
import org.ioriframework.plugin.maven.util.MavenUtils;
import org.ioriframework.plugin.maven.util.PreferenceUtils;
import org.ioriframework.plugin.maven.util.ProcessUtils;

/**
 * 任务处理基类
 * @author iori
 *
 */
public abstract class BaseHandler {

	
	/**
	 * 开始任务
	 */
	public abstract void run();
	
	/**
	 * 构建打包命令
	 * @param command
	 * @return
	 */
	protected String buildCommand(String command) {
		StringBuilder commandBuilder = new StringBuilder();
		// maven home
		commandBuilder.append(MavenUtils.getMavenHome());
		commandBuilder.append(Constants.SPACE);
		// 指定pom.xml路径参数
		commandBuilder.append("-f");
		commandBuilder.append(Constants.SPACE);
		commandBuilder.append("\"");
		// pom.xml路径
		commandBuilder.append(getPomPath());
		commandBuilder.append("\"");
		commandBuilder.append(Constants.SPACE);
		// 命令
		commandBuilder.append(command);
		// 设置当前任务运行的命令
		ConsoleFactory.currentConsole().setCommand(commandBuilder.toString());
		return commandBuilder.toString();
	}
	

	/**
	 * 执行命令
	 * @param command
	 * @return true:命令执行成功
	 * @throws IOException 
	 * @throws InterruptedException 
	 */
	protected void process(String command) throws IOException, InterruptedException {
		Process p = null;
		try {
			ConsoleService.println2Console("Command process begin, command: " + command);
			Runtime rt = Runtime.getRuntime();
			// 记录任务启动前的进程列表
			Set<Integer> pidSet = ProcessUtils.findPids(Constants.JAVA_PROCESS_NAME);
			p = rt.exec(command);
			// 设置任务开始时间
			ConsoleFactory.currentConsole().setStartTime(new Date());
			// 更新控制台描述
			ConsoleFactory.updateDescription();
			// 获取运行命令的返回信息
			InputStream in = p.getInputStream();
			// 转GBK，处理中文乱码
			InputStreamReader isr = new InputStreamReader(in, PreferenceUtils.getString(Constants.P_LOG_ENCODING));
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			// 当强制终止标识为true时，停止输出日志，并退出循环
			while (!ConsoleFactory.currentConsole().isForceTerminate() 
					&& (line = br.readLine()) != null) {
				// 如果当前任务进程为空，则将新增的进程保存，用于强制终止任务时杀进程
				if (ConsoleFactory.currentConsole().getPid() == null) {
					Set<Integer> pidSet2 = ProcessUtils.findPids(Constants.JAVA_PROCESS_NAME);
					for (Integer pid : pidSet2) {
						if (!pidSet.contains(pid)) {
							ConsoleFactory.currentConsole().setPid(pid);
							break;
						}
					}
				}
				// 输出日志到控制台
				ConsoleService.println2Console(line);
			}
			// 当强制终止任务标识为true时，不等待任务执行完毕，直接结束
			if (ConsoleFactory.currentConsole().isForceTerminate()) {
				ConsoleService.println2Console("Command process force terminated, command: " + command);
			} else {
				// 0:表示正常结束， 1:表示非正常结束
				int exitVal = p.waitFor();
				// 成功执行回调
				if (exitVal == 0) {
					processSuccessCallback();
				}
				ConsoleService.println2Console("Command process " + (0 == exitVal ? "end" : "exception") + ",command: " + command);
			}
		} finally {
			if (p != null) {
				p.destroy();
			}
		}
	}
	
	/**
	 * 任务执行成功后的回调函数，用于任务执行成功后处理相应逻辑
	 */
	public abstract void processSuccessCallback();

	/**
	 * 获取pom.xml的路径
	 * @return
	 */
	protected abstract String getPomPath();
	
}
